//
//  KAAFTool.swift
//  kano
//
//  Created by Sophia on 2024/8/15.
//

import UIKit
import AppsFlyerLib


let kAFKey = "EDjvSZJy7U5bac9QfoqJqS"
let kAFAppId = "id6733228838"
let kChannelOrganic = "1522309001"
let kChannelDefault = "1522300099"
let kChannelPre1 = "15223"
let kChannelPre2 = "15113"
let kchannelKey = "lendsafe_channel"

private let single = KAAFTool()

class KAAFTool: NSObject {
    
    static var shared: KAAFTool {
        return single
    }
    
    override init() {
        super.init()
        
        AppsFlyerLib.shared().appsFlyerDevKey = kAFKey
        AppsFlyerLib.shared().appleAppID = kAFAppId
        AppsFlyerLib.shared().delegate = self
//        AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60.0)
        AppsFlyerLib.shared().isDebug = true
    }
    
    static func channel() -> String {
        guard let ch = UserDefaults.standard.string(forKey: kchannelKey) else { return kChannelDefault }
        return ch
    }
    
    static func logEvent(event: String) {
//        AppsFlyerLib.shared().logEvent(event, withValues: [:])
        AppsFlyerLib.shared().logEvent(name: event, values: [:]) { dic, error in
            let data = KALogInfo(classStr: event, logStr: "\(String(describing: error))")
            KAReport.ka_reportWith(type: .log, data: data.kj.JSONObject())
        }
    }
    
    func appFlyerId() -> String {
        AppsFlyerLib.shared().getAppsFlyerUID()
    }
    
    private let maxRetryCount = 3
}


extension KAAFTool: AppsFlyerLibDelegate {

    func onConversionDataSuccess(_ installData: [AnyHashable: Any]) {
        reportInstallData(installData)
        print(">>>>>>>: \(installData)")
        if let status = installData["af_status"] as? String {
            print("installData: \(installData)")
            if (status == "Non-organic") {
                if let campaign = installData["campaign"] {
                    var ch = dealChannel(with: campaign as! String)
                    if ch.isEmpty {
                        ch = installData["af_channel"] as! String
                    }
                    UserDefaults.standard.set(ch, forKey: kchannelKey)
                }
            }else {
                UserDefaults.standard.set(kChannelOrganic, forKey: kchannelKey)
            }
        }
        
        reportChannel()
    }
    
    func reportInstallData(_ installData: [AnyHashable: Any], retryCount: Int = 0) {
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: installData, options: .fragmentsAllowed)
            if let jsonString = String(data: jsonData, encoding: .utf8) {
                let paraDic = [
                    "appsflyerId": AppsFlyerLib.shared().getAppsFlyerUID(),
                    "conversionData": jsonString,
                    "appVersion": KAUserManager.ka_appVersion(),
                    "advertisingId": UIDevice.ka_Idfa(),
                    "idfv": UIDevice.ka_Idfv(),
                    "authentication": kAFKey,
                    "customerUserId": AppsFlyerLib.shared().customerUserID,
                    "pid": "origin",
                    "zuid": UIDevice.ka_UUID,
                    "userGid": KAUserManager.shared.user.userGid,
                    "channel": "",
                ]
//                print("afid_____:\(AppsFlyerLib.shared().advertisingIdentifier)")
//                print("Idfa_____:\(UIDevice.ka_Idfa())")
//                print("Idfv_____:\(UIDevice.ka_Idfv())")

                loginProvider.request(.userAFInfo(paraDic)) { [self] result in
                    switch result {
                    case .success(let response):
                        if response.statusCode == 200 {
                            NetResponse<KAContent>.handleResponseData(response.data) { isSuccess, message, response in
                                if isSuccess == false {
                                    if retryCount < self.maxRetryCount {
                                        DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
                                            self.reportInstallData(installData, retryCount: retryCount + 1)
                                        }
                                    } else {
                                        print("Max retry attempts reached. Returning error.")
                                    }
                                } else {
                                    print("----")
                                }
                            }
                        }else {
                            if retryCount < self.maxRetryCount {
                                DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
                                    self.reportInstallData(installData, retryCount: retryCount + 1)
                                }
                            } else {
                                print("Max retry attempts reached. Returning error.")
                            }
                        }
                    case .failure(let error):
                        if retryCount < self.maxRetryCount {
                            DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
                                self.reportInstallData(installData, retryCount: retryCount + 1)
                            }
                        } else {
                            print("Max retry attempts reached. Returning error.")
                        }
                        print(error.localizedDescription)
                    }
                }
            }
        } catch {
            print("Error converting dictionary to JSON: \(error)")
        }
    }


    func onConversionDataFail(_ error: Error) {
        print(error)
        let data = KALogInfo(classStr: "KAAFTool", logStr: "\(String(describing: error))")
        KAReport.ka_reportWith(type: .log, data: data.kj.JSONObject())
    }
    
    func dealChannel(with campaign: String) -> String {
        var resultChannel = ""
        let channelArray = [kChannelPre1,
                            kChannelPre2]
        for channel in channelArray {
            if campaign.contains(channel) {
                if let range = campaign.range(of: channel) {
                    let index = range.lowerBound
                    resultChannel = String(campaign[index..<campaign.index(index, offsetBy: 10)])
                }
                return resultChannel
            }
        }
        return resultChannel
    }
    
    func reportChannel() {
        if KAUserManager.shared.user.userGid.isEmpty {
            return
        }
        KAReport.ka_reportWith(type: .subChannel)
    }
}
